package aop.aspectj;

import aop.annotation.Custom;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class AspectjDifferentPointcut {
    /**
     * execution(public * *(..)) 任意公共方法的执行
     * execution(* set*(..)) 任何一个以“set”开始的方法的执行
     * execution(* com.xyz.service.AccountService.*(..))  AccountService 接口的任意方法的执行
     * execution(* com.xyz.service.*.*(..)) 定义在service包里的任意方法的执行
     * execution(* com.xyz.service..*.*(..)) 定义在service包和所有子包里的任意类的任意方法的执行
     */
    @Around("execution(* aop.bean.Fish.*(..))") //execution 通过包类路径
    public Object aroundAdvice(ProceedingJoinPoint point) throws Throwable {
        System.out.println(point.getSignature().getName()+"方法执行前（execution）");
        Object result = point.proceed();
        System.out.println(point.getSignature().getName()+"方法执行后（execution）");
        return result;
    }

    /**
     *  注解的其他方法
     *  @within(aop.annotation.Custom) 带注解@Custom的所有类（的所有方法）
     *  @target(aop.annotation.Custom) 带注解@Custom的所有类 （的是所有方法）
     *  @annotation(org.springframework.transaction.annotation.Transactional) 带注解@Custom的所有方法
     */
    @Around(value = "@annotation(around)") //通过注解 around 与下面参数名同
    public Object aroundAdvice2(ProceedingJoinPoint point, Custom around) throws Throwable {
        System.out.println(point.getSignature().getName()+"方法执行前（注解）"+"信息："+around.msg());
        Object result = point.proceed();
        System.out.println(point.getSignature().getName()+"方法执行后（注解）");
        return result;
    }
    /**
     * within(com.test.spring.aop.pointcutexp.*) pointcutexp包里的任意类
     * within(com.test.spring.aop.pointcutexp..*) pointcutexp包和所有子包里的任意类
     * this(com.test.spring.aop.pointcutexp.Intf) 实现了Intf接口的所有类,如果Intf不是接口,限定Intf单个类（当一个实现了接口的类被AOP的时候,用getBean方法必须cast为接口类型,不能为该类的类型）
     *
     */
    @Pointcut("within(aop.bean.*)")
    private void p1(){}

    /**
     * 参数为String类型(运行是决定)的方法
     */
    @Pointcut("args(String)")
    private void p2(){}

}
